package com.zeyu.framework.tools.docconvert.receiver;

import com.zeyu.framework.core.configuration.RabbitMqConfiguration;
import com.zeyu.framework.tools.docconvert.FileConvertHandler;
import com.zeyu.framework.tools.docconvert.OfficeConvertService;
import com.zeyu.framework.tools.docconvert.struct.DocFileInfo;
import com.zeyu.framework.utils.DateUtils;
import com.zeyu.framework.utils.IdGen;
import com.zeyu.framework.utils.PathUtils;
import com.zeyu.framework.utils.SpringContextHolder;
import com.zeyu.framework.utils.StringUtils;
import org.icepdf.core.exceptions.PDFException;
import org.icepdf.core.exceptions.PDFSecurityException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * doc转换信息监听处理器
 * Created by zeyuphoenix on 2016/12/31.
 */
@Component
// @RabbitListener可以修饰Class，表示被修饰的类为消息监听器类，这时候可以使用@RabbitlHandler修饰消息处理方法。
// 同一个消息处理器类中，可以修饰多个消息处理方法，消息处理器会根据监听到的不同消息类型，调用相应的消息处理方法
// 验证后发现,同一个queue, 类上的@RabbitListener > 方法上@RabbitListener > MessageListener接口
@RabbitListener(queues = RabbitMqConfiguration.QUEUE_DOC_CONVERT) //启用Rabbit队列监听doc-convert
public class ConvertMessageListener {

    // ================================================================
    // Constants
    // ================================================================

    /**
     * logger
     */
    private static final Logger logger = LoggerFactory.getLogger(ConvertMessageListener.class);

    // ================================================================
    // Fields
    // ================================================================

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    // 接收到消息处理
    @RabbitHandler
    public void process(@Payload DocFileInfo message) {
        logger.info("接收到doc转换信息: " + message);

        if (message != null && StringUtils.isNotBlank(message.getPath())) {

            if (SpringContextHolder.getBean(OfficeConvertService.class) != null) {

                //转换文件
                convertFile(message);

                //更新文档信息

            } else {
                logger.info("not linux or mac system, or convert service is not loaded!");
            }

        }
    }

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    /**
     * 转换文件
     * @param docFileInfo 转换文件信息
     */
    private void convertFile(DocFileInfo docFileInfo) {

        boolean convertResult = true;

        FileConvertHandler fileConvertHandler = SpringContextHolder.getBean(FileConvertHandler.class);

        // 转换pdf
        if (!FileConvertHandler.FILETYPE_PDF.equalsIgnoreCase(docFileInfo.getExt())) {
            try {
                docFileInfo.setPdfPath(FileConvertHandler.UPLOAD_PATH + getFileUriGeneratedPart(IdGen.uuid(), FileConvertHandler.FILETYPE_PDF));
                fileConvertHandler.office2PDF(PathUtils.getWebRoot() + docFileInfo.getPath(), PathUtils.getWebRoot() + docFileInfo.getPdfPath());
            } catch (IOException e) {
                logger.error("转换pdf发生异常", e);
                convertResult = false;
                docFileInfo.setConState(3);
                docFileInfo.setPdfPath(null);
            }
        }

        if (convertResult) {

            try {
                //生成首页缩略图
                docFileInfo.setThumPath(FileConvertHandler.UPLOAD_PATH + getFileUriGeneratedPart(IdGen.uuid(), FileConvertHandler.FILETYPE_PNG));
                fileConvertHandler.transfer(PathUtils.getWebRoot() + docFileInfo.getPdfPath(), PathUtils.getWebRoot() + docFileInfo.getThumPath(), 1);

                //获取pdf总页数
                int pages = fileConvertHandler.getPdfPages(PathUtils.getWebRoot() + docFileInfo.getPdfPath());
                docFileInfo.setPages(pages);

                //pdf转换swf
                String swfPath = getFileUriGeneratedPart(IdGen.uuid(), FileConvertHandler.FILETYPE_SWF);
                docFileInfo.setSwfPath(FileConvertHandler.UPLOAD_PATH + swfPath.substring(0, swfPath.lastIndexOf("/")));
                fileConvertHandler.pdf2swf(PathUtils.getWebRoot() + docFileInfo.getPdfPath(), PathUtils.getWebRoot() + docFileInfo.getSwfPath());

                docFileInfo.setConState(2);
            } catch (PDFException | PDFSecurityException | IOException e) {
                logger.error("转换swf发生异常", e);
                docFileInfo.setConState(3);
                docFileInfo.setThumPath(null);
                docFileInfo.setPages(0);
                docFileInfo.setSwfPath(null);
            }
        }
    }

    /**
     * 通过文件名后缀创建随机目录(不包括文件名)
     */
    private String getFileUriGeneratedPart(String fileName, String ext) {
        return "/" + DateUtils.getDate("yyyyMMdd") + "/" + fileName.toLowerCase() + "/" + ext + "/" + fileName.toLowerCase() + "." + ext;
    }

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
